/**
 * @author Administrador
 * Created on 17/11/2005
 * Updated on 02/04/2010 by spider
 */
package br.unb.graphics.qos.charts;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;

import br.unb.core.traffic.Traffic;

public class ThroughputChart extends GenericQosChart {

    /**Default Window size in miliseconds */
    private long windowSize = 2000;//USed by loss and throughput
    private static final String THROUGHPUT = "throughput";

    public ThroughputChart(long window) {
        super(THROUGHPUT);
        windowSize = window;
    }

    public void setWindowSize(long windowSize) {
        this.windowSize = windowSize;
        super.setWindowLabel(windowSize);
    }

    public void addQosToTraffic(
            int nrPacket,
            int lenPacket,
            long sendTime,
            long receiveTime,
            String trafficName) {

        Vector values = (Vector) super.vectorsMap.get(trafficName);
        if (values != null) {
            values.add(new Value(receiveTime, lenPacket));
        }
    }

    public void addValuesToCharts() {

        String name = "";
        Vector values;
        Value value;
        long numBytes = 0, firstTime, lastTime;

        Iterator iterator = vectorsMap.keySet().iterator();
        while (iterator.hasNext()) {
            name = (String) iterator.next();
            values = (Vector) vectorsMap.get(name);
            value = new Value(0, 0);

            if (values.size() > 1) {
                value = (Value) values.get(0);
                numBytes = (long) value.getValue();
                firstTime = value.getTimestamp();
                for (int i = 1; i < values.size(); i++) {
                    value = (Value) values.get(i);
                    numBytes += value.getValue();
                }
                lastTime = value.getTimestamp();

                if (lastTime - firstTime > 0) {
                    super.addValueToTraffic(8 * numBytes / ((windowSize) / 1000.0d), lastTime, name);
                }

                values = new Vector();
                values.add(value);
                vectorsMap.put(name, new Vector());
            }
        }
    }

    @Override
    public void loadValuesFromFile(File file) {
        try {
            FileInputStream fis = new FileInputStream(file);
            LineNumberReader lnr = new LineNumberReader(new InputStreamReader(fis));
            String nextStringTraffic = "";
            StringTokenizer st;
            int start = 0;
            String trafficName;
            while (!nextStringTraffic.startsWith("#Traffic:")
                    && ((nextStringTraffic = lnr.readLine()) != null));

            //for(int i = 0; i<4 && ((nextStringTraffic = lnr.readLine())!=null );i++);
            if (nextStringTraffic.startsWith("#Traffic:")) {
                Traffic traffic = Traffic.fromString(nextStringTraffic.substring(nextStringTraffic.indexOf(":") + 1));
                trafficName = traffic.getName();
                start = traffic.getStart();
            } else {
                trafficName = file.getName();
            }

            super.addTraffic(trafficName);
            int lenPacket;
            long receiveTime = 0, firstReceivedTime = 0, refReceiveTime = 0, n = 1;
            int numBytes = 0;
            while ((nextStringTraffic = lnr.readLine()) != null && !nextStringTraffic.startsWith("#NrPacket"));

            if ((nextStringTraffic = lnr.readLine()) != null) {
                st = new StringTokenizer(nextStringTraffic, "\t");
                try {
                    st.nextToken();
                    lenPacket = Integer.parseInt(st.nextToken());
                    st.nextToken();
                    receiveTime = Long.parseLong(st.nextToken());
                    firstReceivedTime = receiveTime;
                    numBytes = lenPacket;
                    refReceiveTime = receiveTime - 3 * 60 * 60 * 1000000L - 1000000L * start;
                } catch (NumberFormatException nfe) {
                }
            }
            while ((nextStringTraffic = lnr.readLine()) != null) {
                st = new StringTokenizer(nextStringTraffic, "\t");
                try {
                    st.nextToken();
                    lenPacket = Integer.parseInt(st.nextToken());
                    st.nextToken();
                    receiveTime = Long.parseLong(st.nextToken());
                    // Band by time
                    if (receiveTime - firstReceivedTime < n * (windowSize) * 1000) {
                        numBytes += lenPacket;
                    } else {//End of window
                        super.addValueToTraffic(
                                (double) (8.0d * numBytes / ((double) (windowSize) / 1000.0d)),
                                (1000 * (windowSize) * n + firstReceivedTime) - refReceiveTime,
                                trafficName);
                        n++;
                        long i = n;
                        long temp = (receiveTime - firstReceivedTime) / (1000 * (windowSize));
                        for (; i <= temp; i++) {
                            super.addValueToTraffic(
                                    0,
                                    (1000 * (windowSize) * n + firstReceivedTime) - refReceiveTime,
                                    trafficName);
                            n++;
                        }
                        numBytes = lenPacket;
                    }
                } catch (NumberFormatException nfe) {
                }
            }
            lnr.close();
            fis.close();
        } catch (IOException ioe) {
        }
        Runtime.getRuntime().gc();
    }
}
